import { extendApi } from '@inbiz/utils';
import {
  formatTreeData,
  updateTreeData,
  findTreeNode,
  findTreeNodes,
  ITreeData,
} from '../../../Tree/preview/web/utils';
export default extendApi(
  (
    _events: any,
    {
      props,
      treeDataRef,
      $expandedKeys,
      $treeData,
      showTreeNameKey,
      treeNodeId,
      treeShowNodeId,
      treeNodeParentId,
      treeShowNodeParentId,
      loadOriginData,
      onChange,
    },
  ) => {
    return {
      getBusinessData: () => {
        return props.businessData;
      },
      getData: () => {
        return treeDataRef.current;
      },
      loadData: (tree: ITreeData, key?: string) => {
        if (tree) {
          if (key) {
            $treeData((origin: any) => {
              return updateTreeData({
                treeData: origin,
                type: 'add',
                keyValue: key,
                data: formatTreeData({
                  data: tree,
                  key: treeShowNodeId,
                  title: showTreeNameKey,
                  childrenKey: 'child',
                  treeNodeId: [treeNodeId, treeShowNodeId],
                  treeNodeParentId: [treeNodeParentId, treeShowNodeParentId],
                  format: (data) => {
                    data.key = data?.key?.toString();
                    data.value = data?.key;
                  },
                }),
              });
            });
          } else {
            $treeData(
              formatTreeData({
                data: tree,
                key: treeShowNodeId,
                title: showTreeNameKey,
                childrenKey: 'child',
                treeNodeId: [treeNodeId, treeShowNodeId],
                treeNodeParentId: [treeNodeParentId, treeShowNodeParentId],
                format: (data) => {
                  data.key = data?.key?.toString();
                  data.value = data?.key;
                },
              }),
            );
          }
        } else {
          return treeDataRef.current;
        }
      },
      setSelect: async (key: string | string[], stauts: boolean) => {
        if (stauts) {
          const values = Array.isArray(key) ? key : [key];
          const notLoadKey: string[] = [];
          findTreeNodes({ treeData: treeDataRef.current, keyValue: values }).forEach(
            (item, index) => {
              if (!item) {
                notLoadKey.push(values[index]);
              }
            },
          );
          if (notLoadKey.length) {
            try {
              await loadOriginData(notLoadKey);
              onChange(key);
              return true;
            } catch (error) {
              return false;
            }
          } else {
            onChange(key);
            return true;
          }
        } else {
          onChange(key);
          return true;
        }
      },
      getText: () => {
        if (props.value) {
          return findTreeNodes({
            treeData: treeDataRef.current,
            keyValue: Array.isArray(props.value) ? props.value : [props.value],
          })
            .map((item) => item.title ?? item.label)
            .join(',');
        } else {
          return '';
        }
      },
      getSelect: () => {
        if (props.multiple) {
          return findTreeNodes({ treeData: treeDataRef.current, keyValue: props.value });
        } else {
          return findTreeNode({ treeData: treeDataRef.current, keyValue: props.value });
        }
      },
      getSaveData: () => {
        if (props.storageConfig && props.childModelConfig) {
          const selectvalue = props.value
            ? Array.isArray(props.value)
              ? props.value
              : [props.value]
            : [];
          const selectNode = selectvalue?.length
            ? findTreeNodes({
                treeData: treeDataRef?.current,
                keyValue: selectvalue,
              })
            : [];
          const saveData = selectNode?.map((item: any) => {
            return props.storageConfig?.tableData.reduce((pre: any, next: any) => {
              pre[next.modelAttr] = item[next.componentAttr];
              pre['_opt'] = 'add';
              return pre;
            }, {});
          }) as { value: string }[];
          return {
            value: props.value,
            childData: {
              controlId: props.controlId,
              modelKey: props.storageConfig?.business,
              datas: [
                ...saveData,
                {
                  _opt: 'del',
                },
              ],
            },
          };
        } else {
          return {
            value: props.value,
          };
        }
      },
      expand: (key: string | string[]) => {
        const expandKeys = Array.isArray(key) ? key : [key];
        $expandedKeys((keys: any) => [...new Set([...keys, ...expandKeys])]);
      },
      collapse: (key: string | string[]) => {
        const isArray = Array.isArray(key);
        $expandedKeys((keys: string[]) => {
          return keys.filter((item) => {
            if (isArray) {
              return !key.includes(item);
            } else {
              return item != key;
            }
          });
        });
      },
    };
  },
);
